package com.snow.useviewdemo.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.GradientDrawable;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zhaoyt on 3/15/23.
 * Describe:线性进度条 可以累加进行
 */
public class LinearProgressBarView extends View {
    // 圆角大小是否自适应为 View 的高度的一半
    private boolean mRadiusAdjustBounds = false;
    private GradientDrawable mDrawableBackground;

    private int mCornerRadius;
    private int mBorderWidth;
    private int mProgressColor = Color.parseColor("#FF4D00");
    private int mBgColor = Color.parseColor("#FFFF9900");

    private RectF mBgRectF = new RectF();

    private Paint mStrokePaint;
    private Paint mFillPaint;

    private int mProgress; // 当前进度
    private long mStartMillis; // 起始时间
    private int mStartProgress; // 起始进度
    private int mTargetProgress; // 目标进度
    private long mTargetMillis; // 目标时间
    private Context mContext;

    public LinearProgressBarView(Context context) {
        this(context, null);
    }

    public LinearProgressBarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LinearProgressBarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        init();
    }

    private void init() {
        int borderWidth = 0;
        int radius = 0;
        int progress = 0;
        GradientDrawable drawableBackground = new GradientDrawable();
        drawableBackground.setColor(mBgColor);
        setBackgroundDrawable(drawableBackground);
        setIsRadiusAdjustBounds(true);
        mBorderWidth = borderWidth;
        mDrawableBackground = drawableBackground;
        mCornerRadius = radius;
        mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mStrokePaint.setStyle(Paint.Style.STROKE);
        mStrokePaint.setStrokeWidth(borderWidth);
        mStrokePaint.setColor(mProgressColor);

        mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mFillPaint.setStyle(Paint.Style.FILL);
        mFillPaint.setColor(mProgressColor);
        setProgress(progress);
    }

    public void setProgressColor(int mProgressColor, int mBgColor) {
        this.mProgressColor = mProgressColor;
        if (mFillPaint != null) {
            mFillPaint.setColor(mProgressColor);
        }

        mDrawableBackground.setColor(mBgColor);
        setBackgroundDrawable(mDrawableBackground);
        this.mBgColor = mBgColor;
    }

    /**
     * 设置进度
     */
    public void setProgress(int progress) {
        setProgress(progress, 0);
    }

    /**
     * 目标时间内绘制目标进度
     *
     * @param progress 目标进度
     * @param millis   到达进度时间段
     */
    public void setProgress(int progress, int millis) {
        if (progress < mProgress) {
            return;
        }
        if (progress < 0) {
            progress = 0;
        }
        if (progress > 100) {
            progress = 100;
        }
        mStartMillis = SystemClock.elapsedRealtime();
        mTargetMillis = mStartMillis + millis;
        mStartProgress = mProgress;
        mTargetProgress = progress;
        invalidate();
    }

    public void resetProgress() {
        mStartMillis = 0;
        mTargetMillis = 0;
        mStartProgress = 0;
        mTargetProgress = 0;
        mProgress = 0;
        invalidate();
    }

    /**
     * 设置圆角大小是否自动适应为 View 的高度的一半
     */
    public void setIsRadiusAdjustBounds(boolean isRadiusAdjustBounds) {
        mRadiusAdjustBounds = isRadiusAdjustBounds;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = getMeasuredHeight();
        int width = getMeasuredWidth();
        if (height > 0 && width > 0) {
            if (mRadiusAdjustBounds) {
                int radius = Math.min(width, height) / 2;
                mDrawableBackground.setCornerRadius(radius);
                mCornerRadius = radius;
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int drawProgress;
        if (mTargetMillis - mStartMillis > 0) {
            drawProgress = mStartProgress + (int) (1.0f * (mTargetProgress - mStartProgress) * (SystemClock.elapsedRealtime() - mStartMillis) / (mTargetMillis - mStartMillis));
            drawProgress = Math.min(mTargetProgress, drawProgress);
        } else {
            drawProgress = mTargetProgress;
        }

        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        RectF rect = mBgRectF;
        float inset = mBorderWidth * 0.5f;
        rect.set(inset, inset, width - inset, height - inset);

        int save = canvas.save();
        canvas.translate(getScrollX(), getScrollY());
        drawProgress(canvas, rect, drawProgress);
        drawBorder(canvas, rect);
        canvas.restoreToCount(save);

        mProgress = drawProgress;
        if (mProgress < mTargetProgress) {
            invalidate();
        }
    }

    /**
     * 进度条
     */
    private void drawProgress(Canvas canvas, RectF rect, int progress) {
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        if (progress == 0) {
            return;
        }

        float factor = progress * 1.0f / 100;
        int save = canvas.save();
        canvas.clipRect(0, 0, factor * width, height);
        canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, mFillPaint);
        canvas.restoreToCount(save);

    }

    /**
     * 进度条边框
     */
    private void drawBorder(Canvas canvas, RectF rect) {
        if (mBorderWidth > 0) {
            canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, mStrokePaint);
        }
    }
}
